Imports System.Reflection
Imports System
Imports System.Activator
Imports System.Type

''' -----------------------------------------------------------------------------
''' Project	 : BizBlox
''' Class	 : BizBlox.DOFactory
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' Create a data object using reflection
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' 	[cinj]	16/06/2006	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Class DOFactory
    Inherits System.MarshalByRefObject
    Private m_objType As Type

    Private Sub New()
    End Sub


    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Create a data object factory using the object as a prototype
    ''' </summary>
    ''' <param name="DOHnd"></param>
    ''' <remarks>
    ''' 
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New(ByVal DOHnd As DataObject)
        m_objType = DOHnd.GetType()
    End Sub


    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Create a data object factory using the type alone
    ''' </summary>
    ''' <param name="DOType"></param>
    ''' <remarks>
    ''' dim f as new DOFactory(GetType(MyDataObject))
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New(ByVal DOType As Type)
        m_objType = DOType
    End Sub

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Return the type of Factory I am
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function getDOType() As Type
        Return m_objType
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' create an empty data object
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Overloads Function Create() As DataObject
        Return CType(Activator.CreateInstance(m_objType), DataObject)
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' create an existing data object which maps to a table guid (existing)
    ''' </summary>
    ''' <param name="uid">GUID of the key in the table</param>
    ''' <returns>data object cast to the correct type</returns>
    ''' <remarks>
    ''' Sets the GUID of the object but does not attempt to load it from the DB
    ''' If the GUID does not exist, an error will only be thrown when the read is 
    ''' attempted.
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Overloads Function Create(ByVal uid As Guid) As DataObject
        Dim obj As DataObject = CType(Activator.CreateInstance(m_objType, New Object() {uid}), DataObject)
        Return obj
    End Function

    ''' <summary>
    ''' create an existing data object which uses a dataset as a populator proxy
    ''' </summary>
    ''' <param name="baseCol">DOCollection which is designed for this DataObject</param>
    ''' <param name="index">index in to the dataset (row) to load from</param>
    ''' <returns>data object cast to the correct type</returns>
    ''' <remarks>This will populate the entire object like as active load.</remarks>
    Public Overloads Function Create(ByVal baseCol As DOCollection, ByVal index As Integer) As DataObject
        Dim obj As DataObject = CType(Activator.CreateInstance(m_objType, New Object() {baseCol, index}), DataObject)
        Return obj
    End Function


    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' create an empty data object and populate it with the data from a Transfer Object
    ''' </summary>
    ''' <param name="transferObject"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' Transfer objects do not need to match all properties of DataObjects to populate them.
    ''' Whatever properties exist of the same type will be populated from the Transfer Object.
    ''' Property names of the Transfer Objects must match the DataObject - case sensitive!
    ''' This allows for cut-down Transfer Objects which exist for a specific task to update or 
    ''' populate a heavy weight DataObject.
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Overloads Function Create(ByVal transferObject As DOTO) As DataObject
        Dim obj As DataObject = CType(Activator.CreateInstance(m_objType), DataObject)
        obj.AcceptTO(transferObject)
        Return obj
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' retrieve (create and load) an existing data object which maps to a table guid
    ''' </summary>
    ''' <param name="uid"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' Sets the GUID of the object and will attempt to load it from the DB
    ''' If the GUID does not exist, an error will be thrown
    ''' 
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Overloads Function Retrieve(ByVal uid As Guid) As DataObject
        Dim obj As DataObject = Create(uid)
        Try
            obj.Load()
        Catch ex As Exception
            Return Nothing
        End Try
        Return obj
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' retrieve (create and load) an existing data object which maps to a table guid
    ''' </summary>
    ''' <param name="transferObject"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' requies a property name which matched the UidColumnName of the DataObject
    ''' the other data in the TransferObject is ignored.
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Overloads Function Retrieve(ByVal transferObject As DOTO) As DataObject
        Dim uid As Guid
        Dim tmpObj As DataObject = CType(Activator.CreateInstance(m_objType), DataObject)
        Dim pInfo As PropertyInfo = transferObject.GetType().GetProperty(tmpObj.UIDColumnName(), GetType(Guid))
        If Not pInfo Is Nothing Then
            uid = transferObject.GetType().InvokeMember(pInfo.Name, BindingFlags.NonPublic Or BindingFlags.GetProperty Or BindingFlags.Public Or BindingFlags.Instance, Nothing, transferObject, New Object() {})
            Return Retrieve(uid)
        Else
            Return Nothing
        End If
    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' retrieve and then import the contents of the DOTO
    ''' allows for 'subset' TOs which do not have all the properties of a DO
    ''' to still be imported.
    ''' </summary>
    ''' <param name="transferObject"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' requies a property name which matched the UidColumnName of the DataObject
    ''' the other data in the transfer object is imported. properties which do not
    ''' map from the transfer object will retain the original data (loads original object first)
    ''' </remarks>
    ''' <history>
    ''' 	[cinj]	26/08/2004	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function Update(ByVal transferObject As DOTO) As DataObject
        Dim obj As DataObject = Retrieve(transferObject)
        If Not obj Is Nothing Then
            obj.AcceptTO(transferObject)
        End If
        Return obj
    End Function

End Class
